using System;
using System.Collections;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.Content;

namespace GameEngine.Shaders
{
    /// <summary>
    /// A class to apply a post render to the device - maybe we need to implement a manager for multiple post processes
    /// </summary>
    public class GEPostProcessor
    {
        private string asset;
        private Effect effect;
        private SpriteBatch spirteBatch;
        private RenderTarget2D renderTarget;

        public Effect Effect { get { return effect; } }

        /// <summary>
        /// Load the effect
        /// </summary>
        /// <param name="device"></param>
        /// <param name="content"></param>
        public void LoadContent(GraphicsDevice device, ContentManager content)
        {
            if (asset!= null)
                effect = content.Load<Effect>(asset);

            renderTarget = new RenderTarget2D(device, device.Viewport.Width, device.Viewport.Height, 1, device.DisplayMode.Format);

            spirteBatch = new SpriteBatch(device);
        }

        /// <summary>
        /// Set the location of the asset - will only have effect next time LoadContent is called
        /// </summary>
        /// <param name="name"></param>
        public void SetAsset(string name)
        {
            asset = name;
        }

        /// <summary>
        /// Reloads the effect
        /// </summary>
        /// <param name="content"></param>
        public void ReloadEffect(ContentManager content)
        {
            if (asset != null)
                effect = content.Load<Effect>(asset);
        }

        public void PreRender(GraphicsDevice device)
        {
            device.SetRenderTarget(0, renderTarget);
        }

        /// <summary>
        /// Actually renders
        /// </summary>
        /// <param name="device"></param>
        public void PostRender(GraphicsDevice device)
        {
            if (asset != null)
            {
                device.SetRenderTarget(0, null);

                effect.CurrentTechnique = effect.Techniques["PostInvert"];
                effect.Begin();
                spirteBatch.Begin(SpriteBlendMode.None, SpriteSortMode.Immediate, SaveStateMode.SaveState);

                foreach (EffectPass pass in effect.CurrentTechnique.Passes)
                {
                    pass.Begin();
                    spirteBatch.Draw(renderTarget.GetTexture(), Vector2.Zero, Color.White);
                    pass.End();
                }

                effect.End();
                spirteBatch.End();
            }
        }
    }
}
